package com.alibaba.citrus.ots.common.util;

import com.alibaba.cz.base.tool.StringUtil;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author yuhailin
 * @description:
 * @date 2021-09-17 17:12
 */
public class DateUtils {

    public static String ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 仅显示年月日，例如 2015-08-11.
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 显示年月日时分秒，例如 2015-08-11 09:51:53.
     */
    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 仅显示时分秒，例如 09:51:53.
     */
    public static final String TIME_FORMAT = "HH:mm:ss";

    /**
     * /带"/"的时间格式
     * */
    public static String PATTEN_SLASH_CN = "yyyy/MM/dd";
    /**
     * 每天的毫秒数 8640000.
     */
    public static final long MILLISECONDS_PER_DAY = 86400000L;

    /**
     * 每周的天数.
     */
    public static final long DAYS_PER_WEEK = 7L;

    /**
     * 每小时毫秒数.
     */
    public static final long MILLISECONDS_PER_HOUR = 3600000L;

    /**
     * 每分钟秒数.
     */
    public static final long SECONDS_PER_MINUTE = 60L;

    /**
     * 每小时秒数.
     */
    public static final long SECONDS_PER_HOUR = 3600L;

    /**
     * 每天秒数.
     */
    public static final long SECONDS_PER_DAY = 86400L;

    /**
     * 每个月秒数，默认每月30天.
     */
    public static final long SECONDS_PER_MONTH = 2592000L;

    /**
     * 每年秒数，默认每年365天.
     */
    public static final long SECONDS_PER_YEAR = 31536000L;

    /**
     * 默认格式
     */
    private static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public static String PATTEN_YMDSF = "yyyy-MM-dd HH:mm";
    public static String PATTEN_YMDS = "yyyy-MM-dd HH";
    /**
     * 日期格式yyyy-MM-dd
     */
    public static String PATTEN_YMD = "yyyy-MM-dd";
    /**
     * 日期格式yyyy年MM月dd日
     */
    public static String PATTEN_YMD_CN = "yyyy年MM月dd日";

    /**
     * 日期格式yyyyMMdd
     */
    public static String PATTEN_YMD_PLAIN = "yyyyMMdd";

    /*
     * 日期格式转时间戳
     */
    public static String dateToStamp(String planTime)  {
        Date date = null;
        if (StringUtil.isNotEmpty(planTime)) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                date = simpleDateFormat.parse(planTime);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return Optional.ofNullable(date).map(o -> String.valueOf(o.getTime())).orElse(null);
    }

    /**
     * 将时间戳转换为时间
     */
    public static String stampToDate(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(Long.parseLong(s));
        return simpleDateFormat.format(date);
    }

    /**
     * 将时间戳转换为时间年月日时分秒
     */
    public static String stampToDate2(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date date = new Date(Long.parseLong(s));
        return simpleDateFormat.format(date);
    }

    /**
     * 时间格式化
     *
     * @param planTime
     * @return
     */
    public static String formatPlanTime(String planTime) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//注意月份是MM
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(simpleDateFormat.parse(planTime));
        int year = calendar.get(Calendar.YEAR);//获取年份
        int month = calendar.get(Calendar.MONTH) + 1;//获取月份
        return year + "年" + month + "月份";
    }

    /**
     * 将字符串转换为日期
     * @param dateStr
     * @return
     */
    public static Date formatString2Date(String dateStr, String pattern) {
        if (StringUtils.isBlank(dateStr) || StringUtils.isBlank(pattern)) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException("dateFormat error!");
        }
        return date;
    }

    public static Date parse(String dateStr) {
        try {
            FastDateFormat simpleDateFormat = FastDateFormat.getInstance("yyyy-MM-dd");
            return simpleDateFormat.parse(dateStr);
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    /**
     * 毫秒值转为格式化的时间字符串
     * @param date
     * @param pattern
     * @return
     */
    public static String toDateStr(Date date,String pattern){
        if(Objects.isNull(date)){
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 毫秒值转为格式化的时间字符串
     * @param timeStamp
     * @param pattern
     * @return
     */
    public static String toDateStr(Long timeStamp,String pattern){
        if(Objects.isNull(timeStamp)){
            return null;
        }
        Date date = new Date(timeStamp);
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static Date obtainCurrentDayBeginOrEnd(Date date,Boolean begin)  {
        if (Objects.isNull(date)) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String dateStr = sdf.format(date);
        if (begin) {
            dateStr = dateStr.split(" ")[0] + " 00:00:00";
        } else {
            dateStr = dateStr.split(" ")[0] + " 23:59:59";
        }
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new IllegalArgumentException(e.getMessage());
        }

    }

    /**
     * 获取当前年份字符串.
     * @return String 当前年份字符串，例如 2015
     * @since 1.0
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取当前月份字符串.
     * @return String 当前月份字符串，例如 08
     * @since 1.0
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }


    /**
     * 获取日期时间字符串，默认格式为（yyyy-MM-dd）.
     * @param date 需要转化的日期时间
     * @param pattern 时间格式，例如"yyyy-MM-dd" "HH:mm:ss" "E"等
     * @return String 格式转换后的时间字符串
     * @since 1.0
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, DateUtils.DATE_FORMAT);
        }
        return formatDate;
    }


    /**
     *  取00:00:00
     *
     * @param source
     * @param
     * @return
     */
    public static Date getFirstTime(String source) {
        Date date = string2Date(source);
        return getFirstTime(date);

    }

    /**
     * 取23:59:59
     * @param source
     * @return
     */
    public static Date getLastTime(String source) {
        Date date = string2Date(source);

        return getLatestTime(date);
    }


    public static Date getFirstTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 00);
        calendar.set(Calendar.MINUTE, 00);
        calendar.set(Calendar.SECOND, 00);
        calendar.set(Calendar.MILLISECOND, 000);
        return calendar.getTime();
    }

    public static Date getNowWithoutHours(){
        Calendar calendar=Calendar.getInstance();
        calendar.set(Calendar.MILLISECOND,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        return calendar.getTime();
    }
    public static Date getLatestTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获取SimpleDateFormat
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getDateParser(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    /**
     * 字符串转换时间
     *
     * @param time
     * @return
     */
    public static Date string2Date(String time) {
        if (StringUtils.isBlank(time)){
            return null;
        }
        switch (time.length()){
            case 8:
                if (time.contains(":")){
                    return string2Date(time, TIME_FORMAT);
                }
                return string2Date(time, PATTEN_YMD_PLAIN);
            case 10:
                if (time.contains("年")){
                    return string2Date(time, PATTEN_YMD_CN);
                }
                if (time.contains("/")){
                    return string2Date(time,PATTEN_SLASH_CN);
                }
                return string2Date(time, PATTEN_YMD);
            case 13:
                return string2Date(time, PATTEN_YMDS);
            case 16:
                return string2Date(time, PATTEN_YMDSF);
            case 19:
                return string2Date(time, DATETIME_FORMAT);
            default:
                return null;
        }

    }

    public static Date string2Date(String time, String pattern) {
        try {
            return getDateParser(pattern).parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date string2Date(String time, DateFormat format) {
        if (StringUtils.isBlank(time)){
            return null;
        }
        try {
            return format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String string2String(String time) {
        Date newDate = string2Date(time);
        return getDateParser(PATTEN_YMD).format(newDate);
    }

    public static Date parseToday(String time) {
        try {
            return DateUtils.parse(time);
        } catch (Exception e) {
           return DateUtils.getFirstTime(new Date());
        }
    }

    public static void main(String[] args) {
        System.out.println(DateUtils.dateToStamp("2021-12-01 00:00:00"));
    }


}

